package com.llap.exp190929.service;

import com.llap.exp190929.dto.CredentialDto;
import com.llap.exp190929.entity.User;
import com.llap.exp190929.error.ForbiddenException;
import com.llap.exp190929.error.RestException;
import com.llap.exp190929.repository.UserRepository;
import com.llap.exp190929.security.MD5PasswordEncoder;
import com.llap.exp190929.util.Util;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.function.Function;

@Service
@AllArgsConstructor
@Slf4j
public class UserService {
    private UserRepository userRepository;
    private static final MD5PasswordEncoder passwordEncoder = new MD5PasswordEncoder();

    public User findUser(int id) {
        return userRepository.findById(id).orElse(null);
    }

    public Page<User> findUsers(int page, int pageSize, String keyword) {
        Pageable paginator = PageRequest.of(page - 1, pageSize);
        if (keyword == null || !keyword.trim().isEmpty()) {
            return userRepository.findAllByUsernameLike("%" + keyword + "%", paginator);
        }
        return userRepository.findAll(paginator);
    }

    public Page<User> findUsers(int page, int pageSize) {
        return findUsers(page, pageSize, null);
    }

    public User findUser(String username) {
        return userRepository.findByUsername(username);
    }

    @Transactional
    public User updateUser(User user) {
        if (user.getId() == null) {
            return null;
        }
        User original = findUser(user.getId());
        if (original == null) {
            return null;
        }
        if (user.getPassword() == null || user.getPassword().isEmpty()) {
            user.setPassword(original.getPassword());
        }
        else {
            user.setPassword(passwordEncoder.encode(user.getPassword()));
        }
        User current = User.from(Util.getLoginUser());
        if (original.getId().equals(current.getId())) {
            user.setAdmin(original.isAdmin());
            user.setSuspended(original.isSuspended());
        }
        user.setUsername(original.getUsername());
        return userRepository.save(user);
    }

    @Transactional
    public User addUser(User user) {
        if (user.getId() != null) {
            return null;
        }
        User u = findUser(user.getUsername());
        if (u == null) {
            user.setPassword(passwordEncoder.encode(user.getPassword()));
            return userRepository.save(user);
        }
        else return null;
    }

    @Transactional
    public void deleteUser(int id) {
        userRepository.deleteById(id);
    }
}
